#!/usr/bin/env python
#coding=utf-8

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from SocketServer import ThreadingMixIn
import cjson

import types,traceback, sys, gzip, cStringIO, time

print cjson.decode('{"Name":"hex","Params":[20]}')
print cjson.encode({"Result":hex(20)})

def compressData(str2Compress):
    """compress to fileObj.
    
        str2Compress: 
            [str2Compress] is a string value to be compressed into cStringIO.StringIO
    """
    fileObj = cStringIO.StringIO()
    g = gzip.GzipFile(mode='wb', compresslevel=9, fileobj=fileObj)
    g.write(str2Compress) #write string and compress
    g.flush() # refresh the buffer which is in gcontent
    g.close()
    return fileObj.getvalue()
#    return fileObj

class ContactField:            
    PIM_BINARY_TYPE = 0
    PIM_BOOLEN_TYPE = 1            
    PIM_DATE_TYPE = 2
    PIM_INT_TYPE = 3            
    PIM_STRING_TYPE = 4
    PIM_STRING_ARRAY_TYPE = 5
    def __init__(self, fieldType=-1, fieldID=-1, attribList=None, jsonArray=None):
        self.fieldType_ = fieldType
        self.fieldID_ = fieldID
        self.attribList_ = attribList                
        if jsonArray:
         self.fromJson(jsonArray)
     
    def fromJson(self, jsonArray):
        self.fieldType_ = jsonArray[0]
        self.fieldID_ = jsonArray[1]
        attribIDList = jsonArray[2]
        attribValueList = jsonArray[3]
        attribList = []
        for index, attribID in enumerate(attribIDList):
            attribList.append( (attribID, self.getPIMValue(attribValueList[index])) )
        self.attribList_ = attribList
     
    def getPIMValue(self, jsonObj):
        if ContactField.PIM_STRING_TYPE == self.fieldType_:
            print "jsonObj", jsonObj[2:]
            print "jsonObj decode", jsonObj[2:].decode("utf-8")
            return jsonObj[2:]
        return jsonObj
    
    def attribsToString(self):
        s = "{"
        for id, value in self.attribList_:
            if types.StringType == type(value):
                s += "id:%d, value:%s\n"%(id, value)
            else:
                s += "id:%d, value:%d\n"%(id, value)
        s += "}"
        return s            
    
    def __str__(self):
        s = "id:%d\n"\
            "type:%d\n"\
            "attribs:%s\n"%(\
            self.fieldID_
            , self.fieldType_
            , self.attribsToString())
        return s


class JSONRequestHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        #step 1:read data from client and decode it
        s = self.rfile.read(int(self.headers['Content-Length']))
        rpcParams = cjson.decode(s)
        print rpcParams
        ret = None
        #step 2:dispath to handling function by function names and parameters
        try:
            ret = getattr(self, 'service_'+rpcParams['Name'])(*rpcParams['Params'])
        except Exception:
        #step 2.1：if has Exception raise , get Errorcode and info to client
            traceback.print_exc(file=sys.stdout)
            ret = cjson.encode({"Exception":{"Code":20001,"Msg":"error!"}})
        #step 3:remove withspace, which can readuce size
        print "before replace withespace:",ret, len(ret)
        retCmp = compressData(ret.replace(" ", ""))
        print "end replace withespace:",ret, len(ret)
        self.send_response( 200 )        
        self.send_header( 'Content-Length', len(retCmp) )
        self.end_headers()
        self.wfile.write( retCmp )
        print '\n', 'time is:' , time.time()
        
    def service_test(self, intVar):
        ret = cjson.encode({"Result":hex(intVar)})
        print ret
#        self.send_header()

        
#    def service_find(self, context, pageNum, pageSize, type):
#        scene = ContactScene("testScene", 1, 1, 1, 1, 1, 1, 1, 1, 11)
#        scene1 = ContactScene("testScene1", 2, 1, 1, 1, 1, 1, 1, 1, 11)
#        scene2 = ContactScene("testScene2", 3, 1, 1, 1, 1, 1, 1, 1, 11)
#        scene3 = ContactScene("testScene3", 4, 1, 1, 1, 1, 1, 1, 1, 11)
#        scene4 = ContactScene("testScene4", 5, 1, 1, 1, 1, 1, 1, 1, 11)
#        scene5 = ContactScene("testScene5", 6, 1, 1, 1, 1, 1, 1, 1, 11)
##        id='', nameSeq=None, phoneSeq=None, emailSeq=None, addrSeq=None, urlSeq=None, photoSeq=None, remarkSeq=None, imSeq=None, sceneSeq=None, defaultScene=0, lastModified=0
#        item = ContactItem("Bruce"        
#                        , ["xinqi", "bruce.xin", "brucexq", "sean"]
#                        , ["13760113672", "28099947"]
#                        , ["brucexq@tom.com", "bruce.xin@gmail.com"]
#                        , ["nangchang", "shengzheng"]
#                        , ["bruce.xin@blogspot.com"]
#                        , []                        
#                        , ["Good guy!"]
#                        , ["188846893", "bruce.sean@hotmail.com"]
#                        , [scene, scene1, scene2, scene3, scene4, scene5]
#                        , 1
#                        , 1111)
#        ret = cjson.encode({"result":{"totalSize":1, "items":[item.toList(),item.toList(),item.toList(),item.toList(),item.toList()]}})
#        print len(ret)
#        self.send_response( 200 )        
#        self.send_header( 'Content-Length', len(ret) )
#        self.end_headers()
#        self.wfile.write( ret )
        
    def service_logIn(self, id, pwd, devicecode):
#        print self.client_address
        return cjson.encode({"Result":id})
        
    def service_signIn(self, info):  
        pass
        
    def service_check(self, id):
        print locals()
        return True

    def service_getCode(self, id):
        print locals()
        return True    

    def service_exit(self, session):    
        print "exit:", locals()  
        return locator.finished(session)       

    def service_getNext(self, pageNum, pageSize, session):
        pass
       
    def service_find(self, session, context, pageNum, pageSize, type):               
        return cjson.encode({"Result":{"totalSize":0, "contactList":[]}})
       
    def service_delete(self, session, idList):
        pass

    def service_add(self, session, contactList):
        pass

    def service_update(self, session, contactList):
        pass

    def service_size(self, session):
        return 0

    def service_lastModified(self, session):
        pass
    
    def service_export(self, session, contacts):
#         public static final int  	ATTR_NONE  	0
#        public static final int 	BINARY 	0
#        public static final int 	BOOLEAN 	1
#        public static final int 	DATE 	2
#        public static final int 	EXTENDED_ATTRIBUTE_MIN_VALUE 	16777216
#        public static final int 	EXTENDED_FIELD_MIN_VALUE 	16777216
#        public static final int 	INT 	3
#        public static final int 	STRING 	4
#        public static final int 	STRING_ARRAY 	5
#        
        print "export"
 
        for contact in contacts:
            for field in contact:
                cf = ContactField(jsonArray=field)
                print cf                
        return ""

    def service_getInfo(self, session):
        pass

    def service_setInfo(self, session, contact):
        pass
    
    def service_incrementFrequency(self, session, id, sceneIdx):
        pass          

class ThreadingServer(ThreadingMixIn, HTTPServer):
    pass


serveraddr = ('', 8080)
srvr = ThreadingServer(serveraddr, JSONRequestHandler)
srvr.serve_forever()
#end



